﻿package org.xhs.report.common.utils
{
    import flash.utils.*;

    public class SWFUtils extends Object
    {
        private static var _bitCursor:uint = 0;
        private static var _bitBuffer:uint = 0;

        public function SWFUtils()
        {
            return;
        }// end function

        public static function analyseSWF(param1:ByteArray, param2:Boolean = true) : Object
        {
            var _loc_10:Object = null;
            var _loc_11:uint = 0;
            var _loc_12:ByteArray = null;
            var _loc_3:Object = {};
            var _loc_4:* = new ByteArray();
            new ByteArray().writeBytes(param1, 0, param1.length);
            _loc_4.endian = Endian.LITTLE_ENDIAN;
            _loc_4.position = 0;
            var _loc_5:* = _loc_4.readUTFBytes(3);
            if (_loc_4.readUTFBytes(3) != "FWS" && _loc_5 != "CWS")
            {
                throw new Error("Fail to analyse that swf. The file is wrong.");
            }
            _loc_3.compressed = _loc_5 == "CWS";
            _loc_3.version = _loc_4.readByte();
            var _loc_6:* = _loc_4.readUnsignedInt();
            _loc_4.readBytes(_loc_4);
            _loc_4.length = _loc_4.length - 8;
            if (_loc_5 == "CWS")
            {
                _loc_4.uncompress();
            }
            _loc_4.position = 0;
            var _loc_13:int = 0;
            _bitCursor = 0;
            _bitBuffer = _loc_13;
            var _loc_7:* = readUB(_loc_4, 5);
            _loc_3.xMin = readSB(_loc_4, _loc_7);
            _loc_3.xMax = readSB(_loc_4, _loc_7);
            _loc_3.yMin = readSB(_loc_4, _loc_7);
            _loc_3.yMax = readSB(_loc_4, _loc_7);
            var _loc_8:* = _loc_4.readUnsignedByte();
            var _loc_9:* = _loc_4.readUnsignedByte();
            _loc_3.fps = _loc_9 + _loc_8 / 256;
            _loc_3.totalFrames = _loc_4.readUnsignedShort();
            if (param2)
            {
                _loc_3.tags = [];
                while (_loc_4.bytesAvailable)
                {
                    
                    _loc_10 = {};
                    _loc_11 = _loc_4.readUnsignedShort();
                    _loc_10.id = _loc_11 >> 6;
                    _loc_10.tagSize = _loc_11 & 63;
                    if (_loc_10.tagSize == 63)
                    {
                        _loc_10.tagSize = _loc_4.readUnsignedInt();
                    }
                    _loc_12 = new ByteArray();
                    if (_loc_10.tagSize != 0)
                    {
                        _loc_4.readBytes(_loc_12, 0, _loc_10.tagSize);
                    }
                    _loc_10.data = _loc_12;
                    _loc_3.tags.push(_loc_10);
                }
            }
            return _loc_3;
        }// end function

        public static function combineSWF(param1:Object) : ByteArray
        {
            var _loc_11:Object = null;
            var _loc_12:ByteArray = null;
            var _loc_13:ByteArray = null;
            var _loc_14:Array = null;
            var _loc_2:* = new ByteArray();
            _loc_2.endian = Endian.LITTLE_ENDIAN;
            _loc_2.writeUTFBytes(param1.compressed ? ("CWS") : ("FWS"));
            _loc_2.writeByte(param1.version);
            _loc_2.writeUnsignedInt(0);
            var _loc_3:* = new ByteArray();
            _loc_3.endian = Endian.LITTLE_ENDIAN;
            var _loc_15:int = 0;
            _bitCursor = 0;
            _bitBuffer = _loc_15;
            var _loc_4:* = Math.max(param1.xMin, param1.xMax, param1.yMin, param1.yMax);
            var _loc_5:* = Math.ceil(Math.log((_loc_4 + 1)) / Math.log(2)) + 1;
            writeUB(_loc_3, _loc_5, 5);
            writeSB(_loc_3, param1.xMin, _loc_5);
            writeSB(_loc_3, param1.xMax, _loc_5);
            writeSB(_loc_3, param1.yMin, _loc_5);
            writeSB(_loc_3, param1.yMax, _loc_5);
            var _loc_6:* = Math.floor(param1.fps);
            var _loc_7:* = (param1.fps - _loc_6) * 256;
            _loc_3.writeByte(_loc_7);
            _loc_3.writeByte(_loc_6);
            _loc_3.writeShort(param1.totalFrames);
            var _loc_8:* = param1.tags;
            var _loc_9:uint = 0;
            while (_loc_9 < _loc_8.length)
            {
                
                _loc_11 = _loc_8[_loc_9];
                _loc_12 = _loc_11.data;
                _loc_13 = new ByteArray();
                _loc_13.endian = Endian.LITTLE_ENDIAN;
                _loc_14 = [];
                if (_loc_12.length >= 63 || _loc_14.indexOf(_loc_11.id) >= 0)
                {
                    _loc_13.writeShort(uint(_loc_11.id) << 6 | 63);
                    _loc_13.writeUnsignedInt(_loc_12.length);
                }
                else
                {
                    _loc_13.writeShort(uint(_loc_11.id) << 6 | _loc_12.length);
                }
                _loc_13.writeBytes(_loc_12);
                _loc_3.writeBytes(_loc_13);
                _loc_9 = _loc_9 + 1;
            }
            var _loc_10:* = _loc_3.length;
            if (param1.compressed)
            {
                _loc_3.compress();
            }
            _loc_2.writeBytes(_loc_3);
            _loc_2.position = 4;
            _loc_2.writeUnsignedInt(_loc_10 + 8);
            _loc_2.position = 0;
            return _loc_2;
        }// end function

        private static function readSB(param1:ByteArray, param2:uint) : int
        {
            var _loc_3:* = readUB(param1, param2);
            var _loc_4:* = 32 - param2;
            var _loc_5:* = _loc_3 << _loc_4 >> _loc_4;
            return _loc_3 << _loc_4 >> _loc_4;
        }// end function

        private static function readUB(param1:ByteArray, param2:uint) : uint
        {
            var _loc_4:int = 0;
            if (param2 == 0)
            {
                return 0;
            }
            if (_bitCursor == 0)
            {
                _bitBuffer = param1.readUnsignedByte();
                _bitCursor = 8;
            }
            var _loc_3:uint = 0;
            while (true)
            {
                
                _loc_4 = param2 - _bitCursor;
                if (_loc_4 > 0)
                {
                    _loc_3 = _loc_3 | _bitBuffer << _loc_4;
                    param2 = param2 - _bitCursor;
                    _bitBuffer = param1.readUnsignedByte();
                    _bitCursor = 8;
                    continue;
                }
                _loc_3 = _loc_3 | _bitBuffer >> -_loc_4;
                _bitCursor = _bitCursor - param2;
                _bitBuffer = _bitBuffer & 255 >> 8 - _bitCursor;
                break;
            }
            return _loc_3;
        }// end function

        private static function writeSB(param1:ByteArray, param2:int, param3:uint) : void
        {
            writeUB(param1, param2 | (param2 < 0 ? (2147483648) : (0)) >> 32 - param3, param3);
            return;
        }// end function

        private static function writeUB(param1:ByteArray, param2:uint, param3:uint) : void
        {
            var bytes:* = param1;
            var value:* = param2;
            var numBits:* = param3;
            var writeU8:* = function (param1:uint) : void
            {
                bytes.writeByte(param1 & 255);
                return;
            }// end function
            ;
            var setU8:* = function (param1:uint) : void
            {
                bytes[(bytes.position - 1)] = param1 & 255;
                return;
            }// end function
            ;
            if (numBits == 0)
            {
                return;
            }
            if (_bitCursor == 0)
            {
                SWFUtils.writeU8(0);
                _bitBuffer = 0;
                _bitCursor = 8;
            }
            while (true)
            {
                
                if (numBits > _bitCursor)
                {
                    SWFUtils.setU8(_bitBuffer | value << 32 - numBits >>> 32 - _bitCursor);
                    numBits = numBits - _bitCursor;
                    SWFUtils.writeU8(0);
                    _bitBuffer = 0;
                    _bitCursor = 8;
                    continue;
                }
                var _loc_5:* = _bitBuffer | value << 32 - numBits >>> 32 - _bitCursor;
                _bitBuffer = _bitBuffer | value << 32 - numBits >>> 32 - _bitCursor;
                SWFUtils.setU8(_loc_5);
                _bitCursor = _bitCursor - numBits;
                break;
            }
            return;
        }// end function

    }
}
